Skip to content

add JSON5 support#185

Merged
payneca merged 10 commits intobecls:devfrom
payneca:cpayne/json
Apr 9, 2026
Merged

add JSON5 support#185
payneca merged 10 commits intobecls:devfrom
payneca:cpayne/json

Conversation

@payneca
Copy link
Copy Markdown
Collaborator

@payneca payneca commented Mar 30, 2026

Fixes

  • fixed an issue where reading a JSON string immediately after a failure to read a string resulted in incorrect output.

  • fixed an issue where reading a JSON float with a large exponent consumed CPU.

Proposed changes

  • require Chez Scheme 10.3.0; drop 9.6.4

  • breaking: change representation of JSON null from the character #\nul to the symbol null

  • breaking: change JSON read and write functions to use options
    This introduces new json:read-options and json:write-options.
    custom-inflate is now the inflate-object field of json:read-options.
    custom-write is now the custom-write field of json:write-options.

  • breaking: move stack->json and json-stack->string to json.ss
    Code that used (import (swish log-db)) may now need (import (swish json)) to access these procedures.

  • A new json5? option allows disabling JSON5 support. By default JSON5 is enabled.

  • A new inflate-symbol option allows raw symbols in JSON-like input to be internalized using a custom function.

  • A new extended-identifiers? option allows raw symbols in JSON-like input to include characters not allowed by the JSON5 identifier syntax.

  • split JSON documentation into a separate chapter

  • export json:key=?

@laqrix laqrix requested a review from burgerrg March 30, 2026 11:19
@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 1, 2026

Now that we don't support Chez 9.6, we should be able to shrink src/swish/compat.ss and possibly move the definitions elsewhere.

@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 1, 2026

In src/swish/software-info.ss, we no longer need to check (top-level-bound? 'scheme-pre-release).

Copy link
Copy Markdown
Collaborator

@burgerrg burgerrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed the documentation and like the changes!

Comment thread src/swish/erlang.ss
Comment thread src/swish/erlang.ss
Comment thread src/swish/erlang.ss Outdated
Comment thread doc/swish/json.tex Outdated
Comment thread doc/swish/json.tex Outdated
Comment thread doc/swish/json.tex Outdated
@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 1, 2026

Please update .github/workflows/test.yml to use actions/checkout@v6.

@payneca payneca force-pushed the cpayne/json branch 2 times, most recently from 4c3d868 to 07dbc08 Compare April 2, 2026 14:33
@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 3, 2026

src/swish/swish-build.ms has comments about 9.5.3 error messages. These can be removed now.

Comment thread doc/reference.bib Outdated
Comment thread src/swish/errors.ss
Comment thread src/swish/software-info.ss Outdated
@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 3, 2026

On line 1386 of erlang.tex, we find:
\var{max-depth} and stops if recognizes a \code{limit-stack} frame.

It should say:
\var{max-depth} and stops if it recognizes a \code{limit-stack} frame.

Comment thread src/swish/json.ss Outdated
Comment thread src/swish/json.ss Outdated
Comment thread src/swish/json.ss
Comment thread src/swish/json.ss
Comment thread src/swish/json.ss
Comment thread src/swish/json.ss Outdated
Comment thread src/swish/json.ss Outdated
Comment thread src/swish/json.ss Outdated
(string-escape ip op))
(unexpected-input 'string (read-char ip) ip))
(read-string ip op mark json5?)]
[(char<=? c #\x1F)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think JSON5 allows control characters to be unescaped.

@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 6, 2026

A micro-benchmark on my laptop indicates that performing a generic hashtable-ref costs ~20 ns, whereas a symbol-hashtable-ref costs ~10 ns. Switching (swish json) to use symbol hash tables roughly doubles the speed of lookups. We go from 30 ns/call to 15 ns/call.

(define json-object (json:make-object [a #t]))

(define (read-json)
  (json:ref json-object 'a #f))

(define (go f)
  (let lp ([n 1000000])
    (unless (#3%fx<= n 0)
      (f)
      (lp (#3%fx- n 1)))))

> (time (go read-json))
(time (go read-json))
    no collections
    0.030847666s elapsed cpu time
    0.031175000s elapsed real time
    8208 bytes allocated
> (exit)
% git stash apply # To use symbol-hashtable
[...]
> (time (go read-json))
(time (go read-json))
    no collections
    0.015209624s elapsed cpu time
    0.015393000s elapsed real time
    3840 bytes allocated

P.S. The allocation appears to occur in other Swish processes, not the benchmark.

@burgerrg
Copy link
Copy Markdown
Collaborator

burgerrg commented Apr 7, 2026

I think all the uses of zero? in json.ss are used on exact numbers, so it would be more efficient to use (eqv? x 0).

@payneca payneca force-pushed the cpayne/json branch 4 times, most recently from adbde9b to b3694b0 Compare April 8, 2026 13:47
Copy link
Copy Markdown
Collaborator

@burgerrg burgerrg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this detailed update!

payneca added 2 commits April 8, 2026 14:04
This introduces new json:read-options and json:write-options.

custom-inflate is now the inflate-object field of json:read-options
payneca added 2 commits April 9, 2026 11:23
- remove (swish compat); move no-inline into erlang.ss

- redefine make-codec-buffer, print-extended-identifiers,
  print-subnormal-precision, transcoded-port-buffer-size

- update all github actions
@payneca payneca merged commit d44bb43 into becls:dev Apr 9, 2026
@payneca
Copy link
Copy Markdown
Collaborator Author

payneca commented Apr 9, 2026

Thanks for the review Bob!

@payneca payneca deleted the cpayne/json branch April 9, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants